/*
 * CustomMenu.h
 *
 *  Created on: 04.05.2009
 *      Author: h3llfire
 */

#ifndef CUSTOMMENU_H_
#define CUSTOMMENU_H_

#include <vector>
#include <wx/object.h>
#include <wx/string.h>
#include <wx/menu.h>
#include "../../core/interfaces/iUserInterface.h"

namespace Impp {

enum CustomMenuEntryType{
	CUSTOM_MENU_ENTRY_NORMAL,
	CUSTOM_MENU_ENTRY_CHECK,
	CUSTOM_MENU_ENTRY_SUBMENU
};


class CustomMenuEntry {

private:
	CustomMenuEntryType type;
	wxString moduleName;
	wxString actionName;
	wxString title;
	wxString help;
	int defaultOrder;
	bool checked;
	int itemId;


public:
	CustomMenuEntry(CustomMenuEntryType type, const wxString & moduleName, const wxString & actionName, const wxString & title, const wxString & help, const int defaultOrder,const bool isChecked = false);
	~CustomMenuEntry();

	CustomMenuEntryType getType() const;
	wxString getModuleName() const;
	wxString getActionName() const;
	wxString getTitle() const;
	wxString getHelpString() const;
	int getDefaultOrder() const;
	bool isChecked() const;
	int getItemId() const;
	void setItemId(int id);
};

class CustomSubMenu;

class CustomSubmenuEntry : public CustomMenuEntry{

private:
	CustomSubMenu* menu;

public:
	CustomSubmenuEntry(CustomSubMenu* menu, const wxString & moduleName, const wxString & actionName, const wxString & title, const wxString & help, const int defaultOrder);
	~CustomSubmenuEntry();

	std::vector<CustomMenuEntry*> getEntries();

};

class CustomMenuBuilder{
private:
	wxString moduleName;
	addMenuItemCallback callback;
public:
	CustomMenuBuilder(const wxString & moduleName, addMenuItemCallback callback);

	wxString getModuleName() const;
	void callAddMenuItemCallback(iMenu* menu, void* userData);

};

class CustomMenu;

class CustomMenuEvtHandler : public wxEvtHandler{
private:
	CustomMenu* menu;

public:
	CustomMenuEvtHandler(CustomMenu* menu);

	void onMenuItem(wxCommandEvent & event);
};

class CustomSubMenu : public iMenu{

	friend class CustomSubmenuEntry;


private:
	CustomMenu* base;
	std::vector<CustomMenuEntry*> entries;

public:
	CustomSubMenu(CustomMenu* base);
	~CustomSubMenu();

	void appendItem(const wxString & actionName, const wxString & item, const int & defaultOrder, const wxString & helpString = wxEmptyString);
	void appendCheckItem(const wxString & actionName, const wxString & item,const bool checked, const int & defaultOrder, const wxString & helpString = wxEmptyString);
	iMenu* appendOrGetSubMenu(const wxString & actionName, const wxString & item, const int & defaultOrder, const wxString & helpString);

};





class CustomMenu : public iMenu{

	friend class CustomSubMenu;

private:
	CustomMenuEvtHandler evtHandler;
	std::vector<CustomMenuBuilder*> builder;
	std::vector<CustomMenuEntry*> entries;
	CustomMenuBuilder* curInvokedBuilder;
	void* userData;

public:
	CustomMenu();
	virtual ~CustomMenu();

	void reigsterMenuEntryAdder(const wxString & moduleName, addMenuItemCallback callback);

	void appendItem(const wxString & actionName, const wxString & item, const int & defaultOrder, const wxString & helpString = wxEmptyString);
	void appendCheckItem(const wxString & actionName, const wxString & item,const bool checked, const int & defaultOrder, const wxString & helpString = wxEmptyString);

	iMenu* appendOrGetSubMenu(const wxString & actionName, const wxString & item, const int & defaultOrder, const wxString & helpString);

	void onMenuItem(wxCommandEvent & event);
	bool checkEntry(CustomMenuEntry* entry, wxCommandEvent & event);

	void buildMenu(wxMenu* menu, void* userData, int firstId);

	void SetNextHandler(wxEvtHandler* handler);

	static bool cmp(CustomMenuEntry* a, CustomMenuEntry* b);
private:
	void buildEntry(CustomMenuEntry* entry, wxMenu* menu, int & curId);
};

}

#endif /* CUSTOMMENU_H_ */
